<?php

namespace core\lib;

/**
 * 日志类
 * Description:
 * 1.自定义日志根目录及日志文件名称。
 * 2.使用日期时间格式自定义日志目录。
 * 3.自动创建不存在的日志目录。
 * 4.记录不同分类的日志，例如信息日志，警告日志，错误日志。
 * 5.可自定义日志配置，日志根据标签调用不同的日志配置。
 */
class Logger
{
    private $_log_path = LOG_PATH;
    // 日志文件
    private $_log_file = 'default.log';
    // 日志自定义目录
    private $_format = 'Ymd';
    // 日志日期标签
    private $_tag = 'default';
    // 总配置设定
    private static $_CONFIG;

    /**
     * 初始化
     */
    public function __construct($config = array())
    {
        // 日志根目录
        if (isset($config['log_path'])) {
            $this->_log_path = $config['log_path'];
        }
        // 日志文件
        if (isset($config['log_file'])) {
            $this->_log_file = $config['log_file'];
        }
        // 日志自定义目录
        if (isset($config['format'])) {
            $this->_format = $config['format'];
        }
        // 日志标签
        if (isset($config['tag'])) {
            $this->_tag = $config['tag'];
        }
    }

    /**
     * 设置配置
     */
    public static function setConfig($config = array())
    {
        self::$_CONFIG = $config;
    }

    /**
     * 获取日志类对象
     */
    public static function getLogger($tag = 'default')
    {
        // 根据tag从总配置中获取对应设定，如不存在使用default设定
        $config = isset(self::$_CONFIG[$tag]) ? self::$_CONFIG[$tag] : (isset(self::$_CONFIG['default']) ? self::$_CONFIG['default'] : array());        // 设置标签
        $config['tag'] = $tag != '' && $tag != 'default' ? $tag : '-';        // 返回日志类对象
        return new Logger($config);
    }

    /**
     * 写入信息日志
     */
    public function info($data, array $extra = [])
    {
        return $this->add('INFO', $data, $extra);
    }

    /**
     * 写入警告日志
     */
    public function warn($data, array $extra = [])
    {
        return $this->add('WARN', $data, $extra);
    }

    /**
     * 写入错误日志
     */
    public function error($data, array $extra = [])
    {
        return $this->add('ERROR', $data, $extra);
    }

    /**
     * 写入日志
     * @param String $type 日志类型
     * @param String $data 日志数据
     * @param array $extra 额外数据
     * @return Boolean
     */
    private function add($type, $data, array $extra = [])
    {
        // 获取日志文件
        $log_file = $this->getLogFile();
        // 创建日志目录
        $is_create = $this->createLogPath(dirname($log_file));
        // 日志内容
        if (is_array($data)) {
            $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        }
        $log_data = sprintf('[%s] %-5s %s %s' . PHP_EOL, date('Y-m-d H:i:s'), $type, $this->_tag, $data);
        if (!empty($extra)) {
            if (is_array($extra)) {
                $log_data .= 'extras:' . json_encode($extra, JSON_UNESCAPED_UNICODE) . PHP_EOL;
            } else {
                $log_data .= 'extras:' . $extra . PHP_EOL;
            }
        }
        // 写入日志文件
        if ($is_create) {
            return @file_put_contents($log_file, $log_data, FILE_APPEND);
        }
        return false;

    }

    /**
     * 创建日志目录
     */
    private function createLogPath($log_path)
    {
        if (!is_dir($log_path)) {
            return mkdir($log_path, 0755, true);
        }
        return true;
    }

    /**
     * 获取日志文件名称
     * @return String
     */
    private function getLogFile()
    {
        return sprintf("%s/%s/%s", $this->_log_path, date($this->_format), $this->_log_file);
    }
}
